//
//  HYQImagePickerManager.m
//  HYQImagePickerController_Example
//
//  Created by zhuxingjian on 2018/8/28.
//  Copyright © 2018年 zxj1989. All rights reserved.
//

#import "HYQImagePickerManager.h"
#import <TZImagePickerController/TZImagePickerController.h>

static const CGFloat defaultMaxVideoDuration = 300.0f;
static const CGFloat thumbImageMaxWidth = 180;

@interface HYQImagePickerManager () <TZImagePickerControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>

@property (nonatomic, strong) TZImagePickerController *imagePickerController;
@property (nonatomic, strong) TZVideoPlayerController *videoPlayerController;
@property (nonatomic, strong) UIImagePickerController *takePhotoController;
@property (nonatomic, assign) HYQImagePickerType pickerType;

@end

@implementation HYQImagePickerManager

- (instancetype)initPickerWithType:(HYQImagePickerType)type;
{
    if (self = [super init]) {
        _imagePickerController = [[TZImagePickerController alloc] initWithMaxImagesCount:(type == HYQImagePickerTypeSinglePhoto ? 1 : 9) delegate:self];
        [self configViewWithType:type];
    }
    return self;
}

- (instancetype)initPreviewPhotoPickerWithType:(HYQImagePickerType)type
                                selectedAssets:(NSMutableArray *)selectedAssets
                                selectedPhotos:(NSMutableArray *)selectedPhotos
                                  currentIndex:(NSInteger)index;
{
    if (self = [super init]) {
        _imagePickerController = [[TZImagePickerController alloc] initWithSelectedAssets:selectedAssets selectedPhotos:selectedPhotos index:index];
        [self configViewWithType:type];
        self.imagePickerController.maxImagesCount = type == HYQImagePickerTypeSinglePhoto ? 1 : 9;
        
        
        /**
         预览完成时回调此方法
         */
        __weak typeof(&*self) weakSelf = self;
        self.imagePickerController.didFinishPickingPhotosHandle = ^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
            [weakSelf imagePickerController:weakSelf.imagePickerController didFinishPickingPhotos:photos sourceAssets:assets isSelectOriginalPhoto:isSelectOriginalPhoto];
        };
    }
    return self;
}

- (instancetype)initPreviewVideoControllerWithAsset:(PHAsset *)asset
{
    if (self = [super init]) {
        _videoPlayerController = [[TZVideoPlayerController alloc] init];
        TZAssetModel *model = [TZAssetModel modelWithAsset:asset type:TZAssetModelMediaTypeVideo timeLength:@""];
        _videoPlayerController.model = model;
    }
    return self;
}

- (instancetype)initWithTakePhotoViewController;
{
    if (self = [super init]) {
        _takePhotoController = [[UIImagePickerController alloc] init];
        _takePhotoController.sourceType = UIImagePickerControllerSourceTypeCamera;
        _takePhotoController.delegate = self;
    }
    return self;
}

- (void)configViewWithType:(HYQImagePickerType)type
{
    _pickerType = type;
    self.imagePickerController.showPhotoCannotSelectLayer = YES;
    self.imagePickerController.showSelectedIndex = YES;
    self.showCamera = NO;
    self.imagePickerController.onlyReturnAsset = YES;
    self.imagePickerController.scaleAspectFillCrop = YES;
    switch (type) {
        case HYQImagePickerTypeSinglePhoto:
        {
            self.imagePickerController.allowPickingVideo = NO;
        }
            break;
        case HYQImagePickerTypeSingleVideo:
        {
            self.imagePickerController.allowPickingImage = NO;
            self.imagePickerController.allowPickingOriginalPhoto = NO;
            self.imagePickerController.maxImagesCount = 1;
            self.imagePickerController.showSelectBtn = NO;
        }
            break;
        case HYQImagePickerTypeOnlyPhoto:
        {
            self.imagePickerController.allowPickingVideo = NO;
        }
            break;
        case HYQImagePickerTypeOnlyVideo:
        {
            self.imagePickerController.allowPickingImage = NO;
            self.imagePickerController.showSelectBtn = NO;
        }
            break;
        default:
            break;
    }
}

#pragma mark ---------- TZImagePickerControllerDelegate ----------
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto;
{
    if (self.imagePickerController.allowCrop == YES && self.pickerType == HYQImagePickerTypeSinglePhoto) {
        if (self.didPickCropPhotoBlock) {
            self.didPickCropPhotoBlock([assets firstObject], [photos firstObject]);
        }
    }else {
        if (self.didPickPhotosBlock) {
            NSMutableArray *thumbs = [NSMutableArray arrayWithCapacity:0];
            for (int i = 0; i < assets.count; i++) {
                [thumbs addObject:@1];
            }
            __block NSInteger flag = 0;
            for (int i = 0; i < assets.count; i++) {
                [[TZImageManager manager] getPhotoWithAsset:assets[i] photoWidth:thumbImageMaxWidth completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
                    if (isDegraded) {
                        return ;
                    }
                    if (photo) {
                        [thumbs replaceObjectAtIndex:i withObject:photo];
                    }
                    if (flag == assets.count - 1) {
                        self.didPickPhotosBlock(assets, thumbs, isSelectOriginalPhoto);
                    }
                    flag ++;
                }];
            }
        }
    }
}

- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos;
{
    
}
//- (void)imagePickerControllerDidCancel:(TZImagePickerController *)picker __attribute__((deprecated("Use -tz_imagePickerControllerDidCancel:.")));
- (void)tz_imagePickerControllerDidCancel:(TZImagePickerController *)picker;
{
    if (self.didCancelPickBlock) {
        self.didCancelPickBlock();
    }
}

// If user picking a video, this callback will be called.
// 如果用户选择了一个视频，下面的handle会被执行
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingVideo:(UIImage *)coverImage sourceAssets:(PHAsset *)asset;
{
    if (self.didPickVideoBlock) {
        self.didPickVideoBlock(asset, coverImage);
    }
}

// If user picking a gif image, this callback will be called.
// 如果用户选择了一个gif图片，下面的handle会被执行
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingGifImage:(UIImage *)animatedImage sourceAssets:(PHAsset *)asset;
{
    
}

// Decide album show or not't
// 决定相册显示与否 albumName:相册名字 result:相册原始数据
- (BOOL)isAlbumCanSelect:(NSString *)albumName result:(PHFetchResult *)result;
{
    return YES;
}

// Decide asset show or not't
// 决定照片显示与否
- (BOOL)isAssetCanSelect:(PHAsset *)asset;
{
    if (asset.mediaType == PHAssetMediaTypeVideo && asset.duration > (self.videoMaxDuration ? self.videoMaxDuration : defaultMaxVideoDuration)) {
        return NO;
    }
    return YES;
}

#pragma mark ---------------- UIImagepickerController delgate ----------------------

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            switch (status) {
                case PHAuthorizationStatusAuthorized: {
                    //  保存图片到相册
                    [[TZImageManager manager] savePhotoWithImage:info[UIImagePickerControllerOriginalImage] completion:^(PHAsset *asset, NSError *error) {
                        if (self.needCrop) {
                            TZImagePickerController *tzpicer = [[TZImagePickerController alloc] initCropTypeWithAsset:asset photo:info[UIImagePickerControllerOriginalImage] completion:^(UIImage *cropImage, PHAsset *asset) {
                                if (self.didPickCropPhotoBlock) {
                                    self.didPickCropPhotoBlock(asset, cropImage);
                                }
                            }];
                            tzpicer.cropRect = [self getCropRectWithScale:self.cropScale];
                            [self.sceneViewController presentViewController:tzpicer animated:YES completion:NULL];
                        }else {
                            [[TZImageManager manager] getPhotoWithAsset:asset photoWidth:thumbImageMaxWidth completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
                                if (isDegraded) {
                                    return ;
                                }
                                if (self.didPickPhotosBlock) {
                                    self.didPickPhotosBlock(@[asset], @[photo], YES);
                                }
                            }];
                        }
                    }];
                    [picker dismissViewControllerAnimated:NO completion:NULL];
                    break;
                }
                    
                case PHAuthorizationStatusDenied: {
                    [picker dismissViewControllerAnimated:YES completion:^{
                        UIAlertController *vc = [UIAlertController alertControllerWithTitle:nil message:@"您已关闭“红演圈”访问相册权限，是否开启访问权限" preferredStyle:UIAlertControllerStyleAlert];
                        UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                            
                        }];
                        UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"前往开启" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                            UIApplication *application = [UIApplication sharedApplication];
                            NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                            if ([application canOpenURL:url]) {
                                if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
                                    [application openURL:url options:@{} completionHandler:nil];
#pragma clang diagnostic pop
                                } else {
                                    [application openURL:url];
                                }
                            }
                        }];
                        [vc addAction:action];
                        [vc addAction:action2];
                        [self.sceneViewController presentViewController:vc animated:YES completion:NULL];
                    }];
                    
                    break;
                }
                    
                case PHAuthorizationStatusRestricted: {
                    break;
                }
                default:
                    break;
            }
        });
    }];
}

- (void)showImagePickerAnimated:(BOOL)animated;
{
    if (!self.sceneViewController) {
        NSLog(@"请设置HYQImagePickerManager的sceneViewController");
    }
    if (self.videoPlayerController) {
         [self.sceneViewController presentViewController:self.videoPlayerController animated:animated completion:NULL];
    }else if (self.takePhotoController) {
        if (![self isCamaraCanUse]) {
            return;
        }
        [self.sceneViewController presentViewController:self.takePhotoController animated:animated completion:NULL];
    }else {
        [self.sceneViewController presentViewController:self.imagePickerController animated:animated completion:NULL];
    }
}

#pragma mark ------------ public setters ---------------
- (void)setSelectedAssets:(NSMutableArray *)selectedAssets
{
    self.imagePickerController.selectedAssets = selectedAssets;
    _selectedAssets = selectedAssets;
}

- (void)setVideoMaxDuration:(NSTimeInterval)videoMaxDuration
{
    _videoMaxDuration = videoMaxDuration;
    self.imagePickerController.videoMaximumDuration = videoMaxDuration;
}

- (void)setMaxImageSelecteCount:(NSInteger)maxImageSelecteCount
{
    _maxImageSelecteCount = maxImageSelecteCount;
    self.imagePickerController.maxImagesCount = maxImageSelecteCount;
}

- (void)setShowCamera:(BOOL)showCamera
{
    self.imagePickerController.allowTakeVideo = showCamera;
    self.imagePickerController.allowTakePicture = showCamera;
    _showCamera = showCamera;
}

- (void)setIsAllowSelectOriginalPhoto:(BOOL)isAllowSelectOriginalPhoto
{
    self.imagePickerController.allowPickingOriginalPhoto = isAllowSelectOriginalPhoto;
    _isAllowSelectOriginalPhoto = isAllowSelectOriginalPhoto;
}

- (void)setIsSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto
{
    self.imagePickerController.isSelectOriginalPhoto = isSelectOriginalPhoto;
    _isSelectOriginalPhoto = isSelectOriginalPhoto;
}

- (void)setNeedCrop:(BOOL)needCrop
{
    self.imagePickerController.allowCrop = needCrop;
    _needCrop = needCrop;
}

- (void)setCropScale:(CGFloat)cropScale
{
    CGFloat maxWidth = CGRectGetWidth([UIScreen mainScreen].bounds);
    CGFloat maxHeight = CGRectGetHeight([UIScreen mainScreen].bounds) - 120;
    CGFloat cropH = maxWidth / cropScale;
    CGFloat cropW = maxWidth;
    if (cropH < maxHeight) {
        self.imagePickerController.cropRect = CGRectMake(0, (maxHeight - cropH + 120) / 2, cropW, cropH);
    }else {
        cropH = maxHeight;
        cropW = cropH * cropScale;
        self.imagePickerController.cropRect = CGRectMake((maxWidth - cropW) / 2, (maxHeight - cropH + 120) / 2, cropW, cropH);
        self.imagePickerController.cropRectPortrait = CGRectMake((maxWidth - cropW) / 2, (maxHeight - cropH + 120) / 2, cropW, cropH);
    }
    _cropScale = cropScale;
}

- (CGRect)getCropRectWithScale:(CGFloat)cropScale
{
    CGFloat maxWidth = CGRectGetWidth([UIScreen mainScreen].bounds);
    CGFloat maxHeight = CGRectGetHeight([UIScreen mainScreen].bounds) - 120;
    CGFloat cropH = maxWidth / cropScale;
    CGFloat cropW = maxWidth;
    if (cropH < maxHeight) {
        return CGRectMake(0, (maxHeight - cropH + 120) / 2, cropW, cropH);
    }
    cropH = maxHeight;
    cropW = cropH * cropScale;
    return CGRectMake((maxWidth - cropW) / 2, (maxHeight - cropH + 120) / 2, cropW, cropH);
}

- (BOOL)isCamaraCanUse
{
    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        UIAlertController *controller = [[UIAlertController alertControllerWithTitle:nil message:@"相机不可用" preferredStyle:UIAlertControllerStyleAlert] init];
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        [controller addAction:action1];
        [self.sceneViewController presentViewController:controller animated:YES completion:NULL];
        return NO;
    }
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied){
        //无权限
        UIAlertController *controller = [[UIAlertController alertControllerWithTitle:@"无法访问相机" message:@"请在iPhone的“设置-隐私-相机”选项中，允许红演圈访问你的相机" preferredStyle:UIAlertControllerStyleAlert] init];
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        [controller addAction:action1];
        UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"去修改" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            UIApplication* application =  [UIApplication sharedApplication];
            if (UIApplicationOpenSettingsURLString != NULL) {
                NSURL *appSettings = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                [application openURL:appSettings];
            }
        }];
        [controller addAction:action2];
        [self.sceneViewController presentViewController:controller animated:YES completion:NULL];
        return NO;
    }
    return YES;
}

@end
